#! /usr/bin/env/python3
# coding:UTF-8
'''
    作者：王楠
    版本: 4.0
    日期：2020/02/29
    功能：输入年月日，判断是这一年的第几天
         模块化，tuple() 改成list()不一样的实现
         改用集合实现set()
         增加dict实现
'''
import datetime


def input_date(input_date_str):
    input_date = datetime.datetime.strptime(input_date_str, '%Y/%m/%d')
    # print(input_date)
    year = input_date.year
    month = input_date.month
    day = input_date.day
    return {'year': year, 'month': month, 'day': day}


def is_leap_year(year):
    is_leap = False
    if (year % 400 == 0) or ((year % 4 == 0) and (year % 100 != 0)):
        is_leap = True
        print('{}年是润年'.format(year))
    else:
        print('{}年不是润年'.format(year))
    return is_leap


def days_num_by_dict(year, month, day):
    days_num = 0
    days_month_dict = {1: 31,
                       2: 28,
                       3: 31,
                       4: 30,
                       5: 31,
                       6: 30,
                       7: 31,
                       8: 31,
                       9: 30,
                       10: 31,
                       11: 30,
                       12: 31}
    days_num += day
    for x in range(1, month):
        if x in days_month_dict.keys():
            days_num += days_month_dict[x]
    if is_leap_year(year):
        if month > 2:
            days_num += 1
    return days_num


def days_num_by_tuple(year, month, day):
    '''
        函数：返回第几天。
    '''
    days_of_month = (31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31)
    days_num = day
    if is_leap_year(year):
        if month > 2:
            days_num += sum(days_of_month[:month-1]) + 1
    else:
        days_num += sum(days_of_month[:month-1])
    return days_num


def days_num_by_list(year, month, day):
    '''
        函数：返回第几天。
    '''
    days_of_month = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
    if is_leap_year(year):
        days_of_month[1] = 29
    days_num = sum(days_of_month[:month - 1]) + day

    return days_num


def days_num_by_set(year, month, day):
    '''
        函数：返回第几天
    '''
    _30_days_month_set = {4, 6, 9, 11}
    _31_days_month_set = {1, 3, 5, 7, 8, 10, 12}
    days_num = day
    for x in range(1, month):
        if x in _30_days_month_set:
            days_num += 30
        elif x in _31_days_month_set:
            days_num += 31
        else:
            days_num += 28
    if is_leap_year(year) and (month > 2):
        days_num += 1
    return days_num


def which_day():
    '''Q
        主函数
    '''
    input_date_str = input('<判断第几天工具，退出请输入：Q>\n请输入日期（yyy/mm/dd）：')
    while input_date_str != 'Q':
        date_dict = input_date(input_date_str)
        # print(date_dict)
        days_num = days_num_by_tuple(date_dict['year'], date_dict['month'], date_dict['day'])
        print('这是{}年的第{}天(bytuple)'.format(date_dict['year'], days_num))
        days_num = days_num_by_list(date_dict['year'], date_dict['month'], date_dict['day'])
        print('这是{}年的第{}天(bylist)'.format(date_dict['year'], days_num))
        days_num = days_num_by_set(date_dict['year'], date_dict['month'], date_dict['day'])
        print('这是{}年的第{}天(byset)'.format(date_dict['year'], days_num))
        days_num = days_num_by_dict(date_dict['year'], date_dict['month'], date_dict['day'])
        print('这是{}年的第{}天(bydict)'.format(date_dict['year'], days_num))

        print('***************************')
        input_date_str = input('<判断第几天工具，退出请输入：Q>\n请输入日期（yyy/mm/dd）：')
        # 输出退出提示
        if input_date_str == 'Q':
            print('工具退出')


if __name__ == '__main__':
    which_day()
